﻿using System;
using System.Drawing;
using System.Windows.Forms;
using System.Threading;

namespace Controller_DLL {
    public partial class Controller : UserControl {
        public EventHandler Changed;

        private Pen mPen;
        private int mEX, mEY;
        private int mPeX, mPeY;

        private Form mMotherForm;

        private readonly Font mDrawFont;
        private readonly SolidBrush mDrawBrush;
        private readonly StringFormat mDrawFormat;

        private int[] mDatas;
        private int mLeft, mRight;

        public Controller() {
            InitializeComponent();

            mPen = new Pen(Color.Blue);

            mDrawFont = new Font("Simplified Arabic Fixed", 8);
            mDrawBrush = new SolidBrush(Color.Black);
            mDrawFormat = new StringFormat();

            mEX = 0; mEY = 0;
            mPeX = 0; mPeY = 0;
            mMotherForm = new Form();
        }

        public void SetMFrom(Form form) {
            mMotherForm = form;
            joystick.Updated += Update;
            joystick.Created += Created;
            joystick.Started += Started;
            joystick.Stopped += Stopped;
            joystick.JoyStateInit(mMotherForm);
        }

        private void SavePrev() {
            mPeX = mEX;
            mPeY = mEY;
        }
        private void SendIfChanged() {
            double egyseg = 125.0 / (125.0 - Math.Abs(mEX));
            mLeft = (int)(mEX >= 0 ? mEY : mEY / egyseg) + 127;
            mRight = (int)(mEX >= 0 ? mEY / egyseg : mEY) + 127;
            int[] tmp = { mLeft, mRight };
            if (mPeX != mEX || mPeY != mEY)
                if (Changed != null) {
                    Changed.Invoke(tmp, new EventArgs());
                    Thread.Sleep(10);
                }
        }
        private void Update(object data, EventArgs e) {
            //keys = false;
            if (data != null) mDatas = data as int[];
            SavePrev();
            mEX = mDatas[0] / 8;
            mEY = -mDatas[1] / 8;
            SendIfChanged();
            Invalidate();
        }

        private void Created(object sender, EventArgs a) {
            Invoke(new MethodInvoker(delegate {
                try { button.Enabled = true; } catch (Exception) { }
            }));
        }
        private void Started(object sender, EventArgs a) {
            Invoke(new MethodInvoker(delegate {
                try { button.Text = "STOP"; } catch (Exception) { }
            }));
        }
        private void Stopped(object sender, EventArgs a) {
            Invoke(new MethodInvoker(delegate {
                try { button.Text = "Use Joystick"; } catch (Exception) { }
            }));
        }

        private void ControllerKeyPress(object sender, KeyPressEventArgs e) {
            if (joystick != null && joystick.IsRun) {
                joystick.StopReading();
                while (joystick.IsRun) Thread.Sleep(2);
            }
            SavePrev();
            switch (e.KeyChar) {
                #region content
                case 'Q': mEX = -125; mEY = 125;
                    break;
                case 'q': mEX = -62; mEY = 62;
                    break;
                case 'W': mEX = 0; mEY = 125;
                    break;
                case 'w': mEX = 0; mEY = 62;
                    break;
                case 'E': mEX = 125; mEY = 125;
                    break;
                case 'e': mEX = 62; mEY = 62;
                    break;
                case 'D': mEX = 125; mEY = 0;
                    break;
                case 'd': mEX = 62; mEY = 0;
                    break;
                case 'C': mEX = 125; mEY = -125;
                    break;
                case 'c': mEX = 62; mEY = -62;
                    break;
                case 'X': mEX = 0; mEY = -125;
                    break;
                case 'x': mEX = 0; mEY = -62;
                    break;
                case 'Y':
                case 'Z': mEX = -125; mEY = -125;
                    break;
                case 'y':
                case 'z': mEX = -62; mEY = -62;
                    break;
                case 'A': mEX = -125; mEY = 0;
                    break;
                case 'a': mEX = -62; mEY = 0;
                    break;
                default:
                    mEX = 0; mEY = 0;
                    break;
                #endregion
            }
            //keys = true;
            SendIfChanged();
            Invalidate();
        }

        private void VisualizerPanelPaint(object sender, PaintEventArgs e) {

            e.Graphics.DrawString("W", mDrawFont, mDrawBrush, 123, 0, mDrawFormat);
            e.Graphics.DrawString("E", mDrawFont, mDrawBrush, 250, 0, mDrawFormat);
            e.Graphics.DrawString("D", mDrawFont, mDrawBrush, 250, 123, mDrawFormat);
            e.Graphics.DrawString("C", mDrawFont, mDrawBrush, 250, 250, mDrawFormat);
            e.Graphics.DrawString("X", mDrawFont, mDrawBrush, 123, 250, mDrawFormat);
            e.Graphics.DrawString("Y", mDrawFont, mDrawBrush, 0, 250, mDrawFormat);
            e.Graphics.DrawString("A", mDrawFont, mDrawBrush, 0, 123, mDrawFormat);
            e.Graphics.DrawString("Q", mDrawFont, mDrawBrush, 0, 0, mDrawFormat);

            e.Graphics.DrawString("w", mDrawFont, mDrawBrush, 124, 63, mDrawFormat);
            e.Graphics.DrawString("e", mDrawFont, mDrawBrush, 188, 63, mDrawFormat);
            e.Graphics.DrawString("d", mDrawFont, mDrawBrush, 188, 124, mDrawFormat);
            e.Graphics.DrawString("c", mDrawFont, mDrawBrush, 188, 188, mDrawFormat);
            e.Graphics.DrawString("x", mDrawFont, mDrawBrush, 124, 188, mDrawFormat);
            e.Graphics.DrawString("y", mDrawFont, mDrawBrush, 63, 188, mDrawFormat);
            e.Graphics.DrawString("a", mDrawFont, mDrawBrush, 63, 124, mDrawFormat);
            e.Graphics.DrawString("q", mDrawFont, mDrawBrush, 63, 63, mDrawFormat);

            e.Graphics.FillRectangle(new SolidBrush(Color.Blue), 120, 120, 20, 20);
            e.Graphics.FillPie(new SolidBrush(Color.Red), mEX + 125, -mEY + 125, 10, 10, 0, 360);


            e.Graphics.DrawString("Left :" + mLeft.ToString(), mDrawFont, mDrawBrush, 10, 10, mDrawFormat);
            e.Graphics.DrawString("Right:" + mRight.ToString(), mDrawFont, mDrawBrush, 10, 20, mDrawFormat);
            e.Graphics.DrawString("ex: " + mEX.ToString(), mDrawFont, mDrawBrush, 10, 30, mDrawFormat);
            e.Graphics.DrawString("ey: " + mEY.ToString(), mDrawFont, mDrawBrush, 10, 40, mDrawFormat);
        }

        private void SetInputDeviceButtonClick(object sender, EventArgs e) {
            if (mMotherForm == null) throw new NullReferenceException("Please first setup the motherForm.");
            if (!joystick.IsRun)
                joystick.StartReading();
            else
                joystick.StopReading();
        }

        public void StopJoy() {
            joystick.Updated = null;
            joystick.Created = null;
            joystick.Started = null;
            joystick.Stopped = null;
            if (joystick.IsRun) joystick.StopReading();
        }

    }
}

